from entity.tool import *
from entity import token

# 文件指针
filePtr = None
# 当前字符
ch = ' '
# 行计数
pos = 1


# 打开文件
def openFile(filename='../resources/test.grammar'):
    global filePtr
    filePtr = open(filename, 'r')
    return filePtr


# 从打开的文件中读取一个字符
def getch():
    global ch
    if filePtr is None:
        return None
    ch = filePtr.read(1)
    # print(ch,end='')
    # print('%s %d' % (ch,ord(ch)))
    # 读到文件末尾
    if len(ch) == 0:
        # 设置为结束符号
        ch = '#'


# 判断字符是否为字母
def isAlpha(ch):
    return ('z' >= ch >= 'a') or (ch <= 'Z') and (ch >= 'A');


# 判断字符是否为数字
def isDigit(ch):
    return '9' >= ch >= '0'


# 读取一个单词，返回一个四元组(类型，名称，值，位置（所在行）)
def getToken():
    global pos
    while ch == ' ' or ch == '\t' or ch == '\n':
        if ch == '\n':
            pos = pos + 1
        getch()
    # print('ch is %s'%ch)
    # 可能为标识符或者关键字
    if isAlpha(ch):
        # 用于读出整个单词
        curToken = ''
        while isAlpha(ch) or isDigit(ch):
            # 拼接
            curToken += ch
            # 继续读
            getch()
        # 如果是关键字
        if curToken in keywordSet:
            return keywordSymMap[curToken], None, None, pos
        # 如果是标识符
        else:
            return ID_SYM, curToken, None, pos
    # 如果遇到的是数字，只能是数字
    elif isDigit(ch):
        num = 0
        while isDigit(ch):
            num = num * 10 + ord(ch) - ord('0')
            getch()
        return UN_SYM, None, num, pos
    elif ch == ':':
        getch()
        if ch == '=':
            getch()
            return GIV_SYM, None, '=', pos
    elif ch == '>':
        getch()
        if ch == '=':
            getch()
            return RE_SYM, None, '>=', pos
        else:
            return RE_SYM, None, '>', pos
    elif ch == '=':
        getch()
        if ch == '=':
            return RE_SYM, None, '==', pos
        else:
            return EQ_SYM, None, None, pos
    elif ch == '<':
        getch()
        if ch == '=':
            getch()
            return RE_SYM, None, '<=', pos
        else:
            return RE_SYM, None, '<', pos

    # 其他的单个符号
    else:
        # 读到文末
        if ch == '#':
            return OVE_SYM, None, '#', pos
        temp = ch
        getch()
        return symSymMap[temp], None, None, pos
        # while


# 关闭文件
def closeFile(filename='../resources/test.grammar'):
    global filePtr
    filePtr.close()


if __name__ == '__main__':
    print('正在进行词法分析...')
    openFile()
    token = (0, 0, 0)
    with open('../outputs/lexicalAnalysis.txt', 'w') as f:
        f.write('tips: (type, name, value, pos)\n')
        while token[2] != '#':
            token = getToken()
            f.write(str(token))
            f.write('\n')
    closeFile()

    print('词法分析完毕，请查看output/lexicalAnalysis.txt文件')
    # print(isAlpha('a'))
